#ifndef _LINUX_RADIX_TREE_H
#define _LINUX_RADIX_TREE_H

#include <linux/types.h>

#define RADIX_TREE_INDIRECT_PTR	1
#define RADIX_TREE_RETRY ((void *)-1UL)

#define RADIX_TREE_MAX_TAGS 2

struct radix_tree_root {
	unsigned int		height;
	gfp_t			gfp_mask;
	struct radix_tree_node	*rnode;
};

#define INIT_RADIX_TREE(root, mask)					\
do {									\
	(root)->height = 0;						\
	(root)->gfp_mask = (mask);					\
	(root)->rnode = NULL;						\
} while (0)

static inline void *radix_tree_ptr_to_indirect(void *ptr)
{
	return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR);
}

static inline int radix_tree_is_indirect_ptr(void *ptr)
{
	return (int)((unsigned long)ptr & RADIX_TREE_INDIRECT_PTR);
}

static inline void *radix_tree_indirect_to_ptr(void *ptr)
{
	return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR);
}

static inline void *radix_tree_deref_slot(void **pslot)
{
	// void *ret = rcu_dereference(*pslot);
	void *ret = *pslot;
	if (radix_tree_is_indirect_ptr(ret))
		ret = RADIX_TREE_RETRY;
	return ret;
}

static inline void radix_tree_preload_end(void)
{
	preempt_enable();
}

#endif
